/*================================================================================
// File Name: sm3_extend.v
// Author: atom
// Created Time: 2023年11月24日 星期五 21时18分31秒
//
//       *         *********       ****            *         *     
//      * *            *          *    *          * *       * *    
//     *   *           *         *      *        *   *     *   *   
//    *******          *         *      *       *     *   *     *  
//   *       *         *          *    *       *       * *       * 
//  *         *        *           ****       *         *         *
================================================================================*/
module sm3_extend(
    input                       clk,
    input                       rst_n,

    input                       din_vld,
    input       [511:0]         din,

    output  reg [67:0] [31:0]   dout,
    output  reg [63:0] [31:0]   dout1,
    output  reg                 dout_vld
);


wire    [67:0] [31:0]       data;
wire    [63:0] [31:0]       data1;
wire    [51:0] [31:0]       tmp;

generate
genvar j;
    for(j=0;i<16;j=j+1)begin:loop_dispatch0
        assign data[j] = din[(j+1)*32-1-:32];

        assign tmp[j]  =    func_sm3_f1(data[j+16-16] ^ data[j+16-9] ^ func_sm3_potr(data[j+16-3],6'd15) ^ func_sm3_potr(data[j+16-13],6'd7) );
        assign data[j+16] = tmp[j] ^ data[j+16-6];

        assign tmp[j+16]  = func_sm3_f1(data[j+32-16] ^ data[j+32-9] ^ func_sm3_potr(data[j+32-3],6'd15) ^ func_sm3_potr(data[j+32-13],6'd7));
        assign data[j+32] = tmp[j+16] ^ data[j+32-6];

        assign tmp[j+32]  = func_sm3_f1(data[j+48-16] ^ data[j+48-9] ^ func_sm3_potr(data[j+48-3],6'd15) ^ func_sm3_potr(data[j+48-13],6'd7));
        assign data[j+48] = tmp[j+32] ^ data[j+48-6];
    end
endgenerate

assign tmp[48]  = func_sm3_f1(data[50] ^ data[55] ^ func_sm3_potr(data[61],6'd15) ^ func_sm3_potr(data[51],6'd7));
assign data[64] = tmp[48] ^ data[60];

assign tmp[49]  = func_sm3_f1(data[51] ^ data[56] ^ func_sm3_potr(data[62],6'd15) ^ func_sm3_potr(data[52],6'd7));
assign data[65] = tmp[49] ^ data[61];

assign tmp[50]  = func_sm3_f1(data[52] ^ data[57] ^ func_sm3_potr(data[63],6'd15) ^ func_sm3_potr(data[53],6'd7));
assign data[66] = tmp[50] ^ data[62];

assign tmp[51]  = func_sm3_f1(data[53] ^ data[58] ^ func_sm3_potr(data[64],6'd15) ^ func_sm3_potr(data[54],6'd7));
assign data[67] = tmp[51] ^ data[63];


generate
genvar k;
    for(k=0;k<64;k=k+1)begin:loop_dout1
        assign data1[k] = data[k] ^ data[k+4];
    end
endgenerate


always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        dout_vld <= 1'b0;
    else
        dout_vld <= din_vld;
end

integer i;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        for(i=0;i<68;i=i+1)
            dout[i] <= 32'b0;
    else
        for(i=0;i<68;i=i+1)
            dout[i] <= data[i];
end

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        for(i=0;i<64;i=i+1)
            dout1[i] <= 32'b0;
    else
        for(i=0;i<64;i=i+1)
            dout1[i] <= data1[i];
end



endmodule
